home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / umich / telecomm / uwsrc.arc / WINMAIN.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-04-29  |  32.5 KB  |  1,334 lines

  1. /* multi-window terminal emulation Version 0.2, May 29th 1986
  2.  *
  3.  * (C) Copyright 1986 Hans-Martin Mosner, University of Dortmund, Germany
  4.  * You may freely use and distribute this program as source
  5.  * and/or binary provided you make no profit with it.
  6.  */
  7.  
  8. #include <obdefs.h>
  9. #include <gemdefs.h>
  10. #include <osbind.h>
  11. #include <stdio.h>
  12. #include <bios.h>
  13. #include <xbios.h>
  14. #include "wind.h"
  15. #include "uw.h"
  16. #include "windefs.h"
  17.  
  18. #define FIRSTOBJ DABOUT
  19. #define LASTOBJ PRTSTOP
  20.  
  21.  
  22. /* global constants
  23.  */
  24.  
  25. extern    int        gl_apid;
  26. extern    struct    wi_str    w[];
  27.  
  28. int    contrl[12];
  29. int    intin[128];
  30. int    ptsin[128];
  31. int    intout[128];
  32. int    ptsout[128];
  33. int    work_in[11];
  34. int    work_out[57];
  35. int    pxyarray[20];
  36. int    msgbuff[8];
  37.  
  38. int    phys_handle, handle;
  39.  
  40. /*
  41.  * Variables used by various routines (miscellaneous).
  42.  */
  43.  
  44. long    dummy;                /* dummy return variable */
  45. int    scr_x, scr_y, scr_w, scr_h;    /* size of screen */
  46. int    key;                /* the key pressed */
  47. int    tmp;                /* temporary for anything... */
  48. char    alert[300];            /* used for alerts */
  49. int    xsiz, ysiz;            /* temporarys for size of window */
  50.  
  51. /*
  52.  * Character stuff (fonts, keymaps).
  53.  */
  54. FNT    *fnttbl[10];            /* List of pointers to fonts avail */
  55. int    fontsavail;            /* Number of fonts available */
  56. FNT    *tempfont;            /* font pointer */
  57. char    *oldshifted;            /* Pointer to old shifted key map. */
  58. char    *oldnormal;            /* Pointer to old normal key map. */
  59. char    *oldcapslock;            /* Pointer to old caps lock key map. */
  60. int    menu_key_map[0x80];        /* menu objects indexed by key map
  61.                        (alt key) read from object file */
  62. int fontmenuobj[] =            /* array of font menu object numbers */
  63.   { FNTBIG,
  64.     FNTSYS,
  65.     FNTOWN,
  66.     FNTALT,
  67.     FNTTINY,
  68.     FNTUNKNW,
  69.     /* Add new font menu items here! */
  70.     0
  71.   };
  72. extern    FNT    *loadfont();
  73.  
  74. /*
  75.  * State (loosely defined).
  76.  */
  77. int    tick;                /* used for flashing cursor */
  78. int    outport;            /* ports used with uw */
  79. int    inwind, outwind;        /* windows for input/output */
  80. int    uw_runs;            /* is uw running ? */
  81. FNT    *curfont;            /* font in use */
  82. int    mouse;                /* is mouse visible ? */
  83. int    menonoff;            /* Menu toggle. */
  84. int    m1inout;            /* mouse event  enter = 0  exit = 1 */
  85. int    sel_inp_mode;            /* input select with right button */
  86. extern int highlighted_wdes;        /* window with text highligted */
  87. #define LOCKLEN 30            /* Max length of lock password */
  88. char    lockword[LOCKLEN];        /* lock password */
  89. char    lockbld[LOCKLEN];        /* lock password build area*/
  90. extern int kermwdes;            /* port number for kermit window */
  91.  
  92. /*
  93.  * Options (somewhat loosely defined).
  94.  */
  95. int    fast;                /* flag for fast open/close */
  96. int    overstrike;            /* flag for character drawing */
  97. int    sliders;            /* flag for sliders on new windows */
  98. int    titles;                /* flag for titles on new windows */
  99. int    audibell;            /* Audible bell. */
  100. int    visibell;            /* Visible bell. */
  101. int    toponbel;            /* Top window on bell. */
  102.  
  103. FUNCSTRING fstrings[NFSTRINGS];        /* storage for function key bodys */
  104.  
  105. char    pastebuff[4096] = "";        /* 50 full lines of text */
  106.  
  107. char    confpath[80] = ".\\*.*";    /* initial config file path */
  108. char    confname[40] = "win.cnf";    /* initial config file name */
  109. int    confbutt;            /* button from fsel_input */
  110.  
  111. /*
  112.  * Screen forms, objects, and other similar goodies...
  113.  */
  114. MFDB    screen_mf;
  115.  
  116. OBJECT    *obj_tmp, *menubar;
  117. TEDINFO    *ted_tmp;
  118. TEDINFO    *ted_fnum;
  119.  
  120. extern struct iorec old_iorec;    /* copy of old rs_232 io record from winio.c */
  121.  
  122. MFORM    rmbmform[1];
  123. MFORM    lckmform[1];
  124.  
  125. #define    CHECKWIN    if (!outwind) break
  126.  
  127. /*
  128.  * The program code...
  129.  */
  130.  
  131. extern    char    *getmem();
  132. #ifdef    MWC
  133. #include <linea.h>
  134. #endif
  135.  
  136. /*
  137.  * If LOCATE is defined, it is assumed to be the path to check after
  138.  * "." for standard files (fonts, config files, etc.).
  139.  */
  140. #ifndef    LOCATE
  141. #define    locate(n)    n
  142. #else
  143. char    locpath[64] = LOCATE;
  144.  
  145. char    *
  146. locate (name)
  147. char    *name;
  148. {
  149.     int    fd;
  150.     static    char    new[80];
  151.  
  152.     close(fd = open(name, 0));
  153.     if (fd >= 0)
  154.         return (name);
  155.  
  156.     sprintf(new, "%s\\%s", locpath, name);
  157.     close(fd = open(new, 0));
  158.     return (fd >= 0? new: name);
  159. }
  160. #endif
  161.  
  162. startup()
  163. {
  164. int i,j;
  165. char *tmpfnt;
  166. static char my_shft_map[128];
  167. static char my_norm_map[128];
  168.  
  169. #ifndef    MWC
  170. register GEMFONT **a5;        /* this is really register A5 */
  171. #endif
  172.  
  173.   /* start up everything: appl_init, menu, and the like
  174.    */
  175.   appl_init();
  176.   rsrc_load(locate("wind.rsc"));
  177.   rsrc_gaddr(R_TREE, MENUBAR, &menubar);
  178.  
  179.   /*
  180.    * Fill menu_key_map by scaning object strings for ALTINDICATOR.
  181.    */
  182.   for (i = FIRSTOBJ; i <= LASTOBJ; i++)
  183.     if (menubar[i].ob_type == G_STRING)
  184.     {
  185.       char * found;
  186.       char * index();
  187.  
  188.       found = index((char *)menubar[i].ob_spec, ALTINDICATOR);
  189.       if (found != NULL)
  190.       {
  191.         menu_key_map[*(++found) & 0x7f] = i;
  192. #ifdef DEBUG
  193.         printf("menu_key_map[%c] = %d\n", *found, i);
  194. #endif
  195.       }
  196.     }
  197.  
  198. /*  objc_change(menubar, VISIBELL, 0, 0, 0, 0, 0, CHECKED, 0); *already done*/
  199.   menu_bar(menubar, menonoff = 1);
  200.   m1inout = 1;
  201.   audibell = 1;
  202.   visibell = 1;
  203.   sliders = 1;
  204.   titles = 1;
  205.  
  206.   /* set mouse symbol to arrow
  207.    */
  208.   graf_mouse(ARROW, NULL);
  209.   mouse = 1;
  210.  
  211.   /* get screen handle and sizes;
  212.    * open virtual workstation
  213.    */
  214.   phys_handle = graf_handle(&dummy, &dummy, &dummy, &dummy);
  215.   wind_get(0, WF_WORKXYWH, &scr_x, &scr_y, &scr_w, &scr_h);
  216.   for (i=0; i<10; work_in[i++]=1);
  217.   work_in[10] = 2;
  218.   handle = phys_handle;
  219.   v_opnvwk(work_in, &handle, work_out);
  220.  
  221.   /* set up screen mfdb
  222.    */
  223.  
  224.   screen_mf.ptr = NULL;
  225.   screen_mf.wpix = 640;
  226.   screen_mf.hpix = 400;
  227.   screen_mf.wwords = 40;
  228.   screen_mf.format = 0;
  229.   screen_mf.planes = 1;
  230.  
  231.   /*
  232.    * now set up the system fonts
  233.    */
  234.   fontsavail = 0;
  235.   if ((curfont = getmem((long)sizeof(FNT))) != NULL)
  236.   {
  237. #ifdef    MWC
  238.     linea0();
  239.     tmpfnt = la_init.li_a1[2]->font_data;    /* 8 x 16 system font */
  240. #else
  241.     asm("dc.w $a000");        /* get font addresses from line A */
  242.     asm("move.l a1,a5");        /* put it into A5 */
  243.     tmpfnt = a5[2]->ft_data;
  244. #endif
  245.     for (i=0; i<128; i++)
  246.       for (j=0; j<16; j++)
  247.         curfont->f_data[i*16+j] = tmpfnt[i+j*256];
  248.     curfont->inc_x = 8;
  249.     curfont->inc_y = 16;
  250.  
  251.     set_menu_string("8 x 16 sys font", fontmenuobj[fontsavail]);
  252.  
  253.     curfont->def_win_x = 80;    /* Set default window size */
  254.     curfont->def_win_y = 24;
  255.  
  256.     gen_hash(curfont, &curfont->f_hash);
  257.  
  258.     fnttbl[fontsavail] = curfont;
  259.     fontsavail++;
  260.   }
  261.   /* set up 6 x 6 system font */
  262.   if ((curfont = getmem((long)sizeof(FNT))) != NULL)
  263.   {
  264. #ifdef    MWC
  265.     linea0();
  266.     tmpfnt = la_init.li_a1[0]->font_data;
  267. #else
  268.     asm("dc.w $a000");        /* get font addresses from line A */
  269.     asm("move.l a1,a5");        /* put it into A5 */
  270.     tmpfnt = a5[0]->ft_data;
  271. #endif
  272.     for (i=0; i<128; i++){ /* for each character (first 128) */
  273.       int bitpos, index, offset;
  274.  
  275.       bitpos = i*6;
  276.       index = bitpos >> 3;
  277.       offset = bitpos & ~(~0<<3);
  278.       for (j=0; j<6; j++) /* for each pixel row in character */
  279.         curfont->f_data[i*16+j+1] = ((tmpfnt[index+j*192] << offset) +
  280.       (tmpfnt[index+j*192+1] >> (8-offset) & ~(~0<<offset)))>>2 & 63;
  281.       curfont->f_data[i*16+0] = 0; /* extra empty row */
  282.     }
  283.     curfont->inc_x = 6;
  284.     curfont->inc_y = 7;
  285.  
  286.     /*
  287.      * The 6x6 system font can be made better.  (dot the i etc.)
  288.      * This is a bad hack, but it makes it easier to read.
  289.      */
  290.     curfont->f_data[105*16+1] = 8;
  291.     curfont->f_data[105*16+2] = 0;
  292.     curfont->f_data[105*16+5] = 8;
  293.     curfont->f_data[106*16+5] = 20;
  294.     curfont->f_data[106*16+6] = 8;
  295.     curfont->f_data[106*16+2] = 0;
  296.  
  297.     curfont->def_win_x = 80;    /* Set default window size */
  298.     curfont->def_win_y = 40;
  299.  
  300.     set_menu_string("6 x 7 sys font", fontmenuobj[fontsavail]);
  301.     gen_hash(curfont, &curfont->f_hash);
  302.  
  303.     fnttbl[fontsavail] = curfont;
  304.     fontsavail++;
  305.   }
  306.  
  307.   /*
  308.    * Load font file(s) if any.
  309.    */
  310.  
  311.   if (curfont = loadfont("windstd.fnt")) /* yes, I want the assignment (=). */
  312.   {
  313.     objc_change(menubar, fontmenuobj[fontsavail-1], 0, 0, 0, 0, 0, CHECKED, 0);
  314.     curfont->def_win_x = 80;    /* Set default window size */
  315.     curfont->def_win_y = 24;
  316.   }
  317.   else {
  318.     objc_change(menubar, FNTSYS, 0, 0, 0, 0, 0, CHECKED, 0);
  319.     curfont = fnttbl[fontsavail - 1];
  320.   }
  321.  
  322.   if (tempfont = loadfont("windalt.fnt"))
  323.   {
  324.     tempfont->def_win_x = 80;    /* Set default window size */
  325.     tempfont->def_win_y = 32;
  326.   }
  327.  
  328.   if (tempfont = loadfont("windtny.fnt"))
  329.   {
  330.     tempfont->def_win_x = 80;    /* Set default window size */
  331.     tempfont->def_win_y = 48;
  332.   }
  333.   if (tempfont = loadfont("windoth.fnt"))
  334.   {
  335.     tempfont->def_win_x = 80;    /* Set default window size */
  336.     tempfont->def_win_y = 24;
  337.   }
  338.   
  339.   /*
  340.    * Disable unused font entrys.
  341.    */
  342.   for (i = fontsavail; fontmenuobj[i] != 0; i++)
  343.   {
  344.     set_menu_string("unavailable font", fontmenuobj[i]);
  345.     objc_change(menubar, fontmenuobj[i], 0, 0, 0, 0, 0, DISABLED, 0);
  346.   }
  347.     
  348.  
  349.   /* set up the serial line (XON/XOFF flow control)
  350.    */
  351.  
  352.   Rsconf(-1, 1, -1, -1, -1, -1);
  353.  
  354.   /* Initalize function keys to default values.
  355.    */
  356.   for (i=0; i<NFSTRINGS; i++)
  357.   {
  358.     sprintf(fstrings[i], "^A%d^M", i);
  359.   }
  360.   fstrings[NFSTRINGS-1][0] = '\0'; /* last function zero length for coding */
  361.  
  362.   /* Set up the key tables to use the help key for break.
  363.    */
  364.   oldshifted = ((struct keytbl *) Keytbl(-1L, -1L, -1L))->kt_shifted;
  365.   oldnormal = ((struct keytbl *) Keytbl(-1L, -1L, -1L))->kt_normal;
  366.   oldcapslock = ((struct keytbl *) Keytbl(-1L, -1L, -1L))->kt_capslock;
  367.  
  368.   for (i=0; i<128; i++) { /* copy bios tables */
  369.     my_shft_map[i] = oldshifted[i];
  370.     my_norm_map[i] = oldnormal[i];
  371.   }
  372.  
  373.   my_shft_map[KC_HELP] = 0x6f; /* except help key */
  374.   for (i=KC_F1; i<=KC_F10; i++) { /* and function keys */
  375.     my_norm_map[i] = 0x6f;
  376.   }
  377. #ifdef COMMENT
  378.   /*
  379.    * These keys must be decoded manualy so that the field editing
  380.    * of gem will not be impacted.
  381.    */
  382.   my_norm_map[KC_CDOWN] = 0x0a; /* and cursor motion keys (for adm31) */
  383.   my_norm_map[KC_CLEFT] = 0x08;
  384.   my_norm_map[KC_CRIGHT] = 0x0c;
  385.   my_norm_map[KC_CUP] = 0x0b;
  386. #endif
  387. /* (void) Keytbl(my_norm_map, my_shft_map, my_norm_map); */
  388.   (void) Keytbl(my_norm_map, my_shft_map, -1L);
  389.   
  390.   form_dial(FMD_START, 0, 0, 0, 0, scr_x, scr_y, scr_w, scr_h);
  391.   form_dial(FMD_FINISH, 0, 0, 0, 0, scr_x, scr_y, scr_w, scr_h);
  392.   
  393.   /*
  394.    * Read initial configuration file if any
  395.    */
  396.   read_config("", locate(confname));
  397. }
  398.  
  399. finish()
  400. {
  401. int i;
  402. struct iorec *ioptr;
  403.  
  404.   /* close all windows and clean up
  405.    */
  406.  
  407.   if (uw_runs) xmitcmd(CB_FN_MAINT|CB_MF_EXIT);
  408.   for (i=0; i<MAX_WIND; i++)
  409.     w_close(i);
  410.   (void) Keytbl(oldnormal, oldshifted, oldcapslock); /* restore key maps */
  411.  
  412.   if (old_iorec.io_bufsiz != 0) {
  413.     ioptr = Iorec(0);    /* restore rs_232 io record */
  414.     *ioptr = old_iorec;
  415.   }
  416.  
  417.   menu_bar(menubar, 0);
  418.   v_clsvwk(handle);
  419.   appl_exit();
  420.   exit();
  421. }
  422.  
  423. memory()
  424. {
  425. long m = Malloc(-1L);
  426.  
  427.   sprintf(alert, "[0][Free memory: %ld bytes][Ok]", m);
  428.   form_alert(1, alert);
  429. }
  430.  
  431. main()
  432. {
  433.   long _stksiz = 4096l;        /* Tell Mark Williams C we need 4k stack */
  434.   int    event;
  435.   int    menuitem = 0;        /* Alt sequence mapped to menu item */
  436.   int    cx, cy, cw, ch;
  437.   int    mx, my, mb, mk;        /* mouse coordinates from event_multi */
  438.   int    ww, wh;            /* window width & height for move */
  439.   int    buttonstate = 2;    /* button state to wait for next. */
  440.   int    clicks;            /* number of clicks seen by evnt_multi. */
  441.   register int    cnt;
  442.   int    funcindex = 0;
  443.   int    regionflag = 0;        /* indicates region selection in progress */
  444.   int    locked = 0;        /* keyboard and mouse locked with password ?*/
  445.   startup();
  446.  
  447.   xsiz = curfont->def_win_x;
  448.   ysiz = curfont->def_win_y;
  449.  
  450. init:
  451.   w_open(1, "Terminal", xsiz, ysiz);
  452.   outport = 1;
  453.   inwind = outwind = find_wind(1);
  454.   printer_mark(outwind);
  455.  
  456.   for (;;)
  457.   {
  458.     if (!mouse)
  459.     {
  460.       graf_mouse(M_ON, NULL);
  461.       ++mouse;
  462.     }
  463.     if (menuitem)
  464.     {
  465.       event = MU_MESAG;
  466.       msgbuff[0] = MN_SELECTED;
  467.       msgbuff[4] = menuitem;
  468.       menuitem = 0;
  469.     }
  470.     else
  471.     {
  472.       event = evnt_multi(MU_MESAG | MU_KEYBD | MU_TIMER | MU_BUTTON | MU_M1,
  473.     2, 2, buttonstate,
  474.     m1inout, scr_x, scr_y, scr_w, scr_h,
  475.     0, 0, 0, 0, 0,
  476.     msgbuff, 15, 0,
  477.     &mx, &my, &mb, &mk,
  478.     &key, &clicks);
  479.     }
  480.  
  481.     if (event & MU_KEYBD)
  482.     if (locked) {
  483.       static char lockkey[LOCKLEN];
  484.       static int lockindex;
  485.       int keyval = key & 0xff;
  486.       
  487.       if (keyval == '\r') {
  488.         lockkey[lockindex] = '\0';
  489.         if (strcmp (lockkey, lockword) == 0) {
  490.           graf_mouse(ARROW, &dummy);
  491.           menu_bar(menubar, menonoff);
  492.       locked = 0;
  493.     }
  494.     lockindex = 0;
  495.       }
  496.       else 
  497.         if (lockindex < LOCKLEN - 1)
  498.           lockkey[lockindex++] = keyval;
  499.     }
  500.     else
  501.     {
  502.       int i, j;
  503.       int outcount;
  504.       int keyindex = key >> 8;
  505.       int keyval = key & 0xff;
  506.       int funcindex = NFSTRINGS;
  507.       char outputstring[MAXFUNCLEN];
  508.  
  509. #ifdef DEBUG
  510.       printf("keyindex = %x, keyval = %x\n", keyindex, keyval);
  511. #endif
  512.  
  513.       /*
  514.        * Decode key for function keys or other special keys
  515.        * This section could be made faster at the expense of less clear
  516.        * code.  It seems to be fast enough for now. (How fast can you type?)
  517.        * It should probrably be table driven.
  518.        */
  519.       if (keyindex >= KC_F1 || (keyval == 0 
  520.         && keyindex != 0x39 /* ctl-space */ && keyindex != 3 /* ctl-@ */))
  521.       {    /* decode these keys manualy */
  522.         if (keyindex >= KC_F1 && keyindex <= KC_F10) /* Unshifted F keys */
  523.         {
  524.       if (keyval == 0x6f)    /* plain function key */
  525.         funcindex = keyindex - KC_F1;
  526.  
  527.       else if (keyval == 0x0f)/* control function key */
  528.         funcindex = keyindex - KC_F1 + 10;
  529.  
  530.       else if (keyval == 0)    /* alt function key */
  531.         funcindex = keyindex - KC_F1 + 30;
  532.         }
  533.  
  534.         else if (keyindex >= KC_F1+25 && keyindex <= KC_F10+25) /* shift F */
  535.           funcindex = keyindex - KC_F1 - 25 + 20;
  536.  
  537.     else if (key == (KC_CDOWN << 8))
  538.       keyval = 0x0a;
  539.  
  540.     else if (key == (KC_CLEFT << 8))
  541.       keyval = 0x08;
  542.  
  543.     else if (key == (KC_CRIGHT << 8))
  544.       keyval = 0x0c;
  545.  
  546.     else if (key == (KC_CUP << 8))
  547.       keyval = 0x0b;
  548.  
  549.         else if (key == 0x626f) /* break key (shift help) */
  550.         {
  551.           long    clk_time;
  552.     
  553.       clk_time = clock();
  554.       Rsconf(-1, -1, -1, -1, 9, -1); /* set break condition */
  555.       while (clock() - clk_time < BREAK_TICKS); /* delay while break is sent */
  556.       Rsconf(-1, -1, -1, -1, 1, -1); /* clear break condition */
  557.       funcindex = NFSTRINGS - 1; /* last function key is zero length */
  558.     }
  559.     else if (keyval == 0)
  560.     {    /* check if alt key used to select menu entry */
  561.       if (keyindex >= 0x78 && keyindex <= 0x7e)
  562.       {    /* alt number used to select window number */
  563.         int newwind = keyindex - 0x77;
  564.  
  565.         if (find_port(newwind) > 0)
  566.           w_top(newwind);
  567.       }
  568.       else
  569.       {    /* alt key short-hand--fake menu message next time around */
  570.         menuitem = menu_key_map[oldnormal[keyindex] & 0x7f];
  571. #ifdef DEBUG
  572.         printf("menu keyindex = %x, char = %c, menuitem = %d\n",
  573.           keyindex, oldnormal[keyindex], menuitem);
  574. #endif
  575.       }
  576.       funcindex = NFSTRINGS - 1; /* last function key is zero length */
  577.     }
  578.       }
  579.       if (funcindex < NFSTRINGS) /* if function key */
  580.       {        /* copy function string to outputstring decoding ^ */
  581.     j=0;
  582.     outcount = 0;
  583.         for (i=0; fstrings[funcindex][i] != '\0'; i++)
  584.     {
  585.       outputstring[j] = fstrings[funcindex][i];
  586.       if (outputstring[j] == '^')
  587.       {
  588.         i++;
  589.         if (fstrings[funcindex][i] == '?')
  590.           outputstring[j] = '\177';
  591.         else if (fstrings[funcindex][i] != '^')
  592.           outputstring[j] = fstrings[funcindex][i] & 0x1f;
  593.       }
  594.       j++;
  595.     }
  596.     outcount = j;
  597.       }
  598.       else    /* normal key press */
  599.       {
  600.         outputstring[0] = keyval & 0x7f;
  601.     outcount = 1;
  602.       }
  603.       /*
  604.        * Now output outcount characters which are stored in outputstring.
  605.        */
  606.       proto_out(outport, outputstring, outcount);
  607.     }
  608.  
  609.     if (event & MU_TIMER)
  610.     {
  611.       if (tick++ > 20)
  612.       {
  613.     w_flash(outwind, 2);
  614.     tick = 0;
  615.     if (kermwdes) kermtimchk();
  616.       }
  617.       /* act on any input from serial port */
  618.       if (proto_in () < 0) goto init    /* uw mode ended? */;
  619.     }
  620.  
  621.     if (event & MU_MESAG)
  622.     {
  623.       switch (msgbuff[0])
  624.       {
  625.       case MN_SELECTED:
  626.     switch (msgbuff[4])
  627.     {
  628.     case REMSHELL:
  629.     case SHELLOTH:
  630.     case SHELL32:
  631.     case SHELL24:
  632.     case SHELL12:
  633.     case SHELL8:
  634.       if (msgbuff[4] == REMSHELL)
  635.       {    /* default window size */
  636.             xsiz = curfont->def_win_x;
  637.         ysiz = curfont->def_win_y;
  638.       }
  639.       else if (msgbuff[4] == SHELLOTH)
  640.       {
  641.         if (!size_dial()) break;
  642.       }
  643.       else
  644.       {    /* size specified in menu string */
  645.         char *ent_str;
  646.  
  647.         ent_str = (char *) menubar[msgbuff[4]].ob_spec;
  648.         sscanf(ent_str, "%*s%d%*s%d", &ysiz, &xsiz);
  649.       }
  650.       if (uw_runs)
  651.       {
  652.         tmp = w_open(0, "Terminal", xsiz, ysiz);
  653.         if (tmp)
  654.         {
  655.           outport = tmp;
  656.           outwind = find_wind(tmp);
  657.           xmitcmd(CB_FN_NEWW|tmp);
  658.         }
  659.       } else
  660.       {
  661.         form_alert(1, "[1][UW is not running][Ok]");
  662.       }
  663.       break;
  664.  
  665.     case LOCCOPY:
  666.       for (cnt=1; cnt<MAX_WIND; cnt++)
  667.       {
  668.         if (!find_wind(cnt))
  669.         {
  670.           break;        /* a free port */
  671.         }
  672.       }
  673.       if (cnt < MAX_WIND)
  674.       {
  675.         static int c[8];
  676.         struct wi_str *wp1 = &w[outwind];
  677.         struct wi_str *wp2;
  678.         outport = w_open(cnt, "Local Copy", wp1->x_chrs, wp1->y_chrs);
  679.         outwind = find_wind(outport);
  680.         wp2 = &w[outwind];
  681.         c[0] = wp1->m_off;
  682.         c[1] = wp1->top_y;
  683.         c[2] = c[0] + wp1->wi_mf.wpix;
  684.         c[3] = c[1] + wp1->wi_mf.hpix;
  685.         c[4] = wp2->m_off;
  686.         c[5] = wp2->top_y;
  687.         c[6] = c[4] + wp2->wi_mf.wpix;
  688.         c[7] = c[5] + wp2->wi_mf.hpix;
  689.         vro_cpyfm(handle, FM_COPY, c, &wp1->wi_mf, &wp2->wi_mf);
  690.         wp2->w_local = TRUE;
  691.       }
  692.       break;
  693.  
  694.     case WINRESIZ:
  695.       if (!size_dial()) break;
  696.       w_resize(outwind, xsiz, ysiz);
  697.       break;
  698.  
  699.     case FQUIT:
  700.       finish();
  701.  
  702.     case FQUITUW:
  703.       if (uw_runs)
  704.       {
  705.       int i;
  706.         xmitcmd(CB_FN_MAINT|CB_MF_EXIT);
  707.         uw_runs = 0;
  708.         for (i=1; i<8; i++)
  709.         {
  710.           w_close(find_wind(i));
  711.         }
  712.         menu_tnormal(menubar, msgbuff[3], 1);
  713.         goto init;
  714.       }
  715.       break;
  716.  
  717.     case LOADCONF:
  718.       fsel_input(confpath, confname, &confbutt);
  719.       if (confbutt) 
  720.         read_config(confpath, confname);
  721.       break;
  722.  
  723.     case SAVECONF:
  724.       fsel_input(confpath, confname, &confbutt);
  725.       if (confbutt) 
  726.         write_config(confpath, confname);
  727.       break;
  728.  
  729.     case CAPTURE:
  730.       if (outwind)
  731.       {
  732.         WI_STR *wp = &w[outwind];
  733.  
  734.         fsel_input(wp->wi_fpath, wp->wi_fname, &confbutt);
  735.         if (confbutt)
  736.           setcapture(wp);
  737.       }
  738.       break;
  739.  
  740.     case COMMAND:
  741.       do_exec();
  742.       break;
  743.  
  744.     case SETPATH:
  745.       do_path();
  746.       break;
  747.  
  748.     case KERMIT:
  749.       kerminit(outwind);
  750.       break;
  751.  
  752.     case FLOCKKEY:
  753.       s_dial(LOCKINFO, 1);
  754.       cnt = 0;
  755.       while ((key = evnt_keybd() & 0xff) != '\r') {
  756.         if (key == '\033') {    /* ESC means use old password */
  757.           locked = 1;
  758.           strcpy(lockbld, lockword);
  759.           break;
  760.         }
  761.         if (cnt < LOCKLEN - 1)
  762.           lockbld[cnt++] = key;
  763.       }
  764.       while (! locked) {
  765.         lockbld[cnt] = '\0';
  766.         locked = 1;
  767.         cnt = 0;
  768.         while ((key = (evnt_keybd() & 0xff)) != '\r')
  769.           if (cnt < LOCKLEN - 1)
  770.             if (key != lockbld[cnt++]) {
  771.           locked = 0;
  772.           lockbld[cnt - 1] = key;
  773.         }
  774.         if (lockbld[cnt] != '\0')
  775.           locked = 0;
  776.       }
  777.       if (lockbld[0] == '\0')
  778.         locked = 0;
  779.       if (locked) {
  780.         strcpy(lockword, lockbld);
  781.         menu_bar(menubar, 0);
  782.         graf_mouse(USER_DEF, lckmform);
  783.       }
  784.       s_dial(LOCKINFO, 2);
  785.       break;
  786.  
  787.     case DABOUT:
  788.       if (s_dial(ABOUT, 3) == MOREINF1)
  789.       {
  790.         if (s_dial(INFO1, 3) == CONT1)
  791.         {    /* give short help screens */
  792.           if (s_dial(INFO2, 3) == CONT2)
  793.           {
  794.             if (s_dial(INFO3, 3) == CONT3)
  795.             {
  796.               if (s_dial(INFO4, 3) == CONT4)
  797.               {
  798.             s_dial(INFO5, 3);
  799.               }
  800.             }
  801.           }
  802.         }
  803.       }
  804.       break;
  805.  
  806.     case WRENAME:
  807.       CHECKWIN;
  808.       rsrc_gaddr(R_TREE, NEWNAME, &obj_tmp);
  809.       ted_tmp = (TEDINFO *) obj_tmp[FLD1].ob_spec;
  810.       strcpy(ted_tmp->te_ptext, w[outwind].name);
  811.       form_center(obj_tmp, &cx, &cy, &cw, &ch);
  812.       form_dial(FMD_START, 0, 0, 20, 10, cx, cy, cw, ch);
  813.       if (!fast) form_dial(FMD_GROW, 0, 0, 20, 10, cx, cy, cw, ch);
  814.       objc_draw(obj_tmp, 0, 5, cx, cy, cw, ch);
  815.       tmp = form_do(obj_tmp, FLD1);
  816.       if (!fast) form_dial(FMD_SHRINK, 0, 0, 20, 10, cx, cy, cw, ch);
  817.       form_dial(FMD_FINISH, 0, 0, 20, 10, cx, cy, cw, ch);
  818.       objc_change(obj_tmp, tmp, 0, cx, cy, cw, ch, NONE, 0);
  819.       if (tmp == OKRENAME) w_rename(outwind, (char *) ted_tmp->te_ptext);
  820.       break;
  821.  
  822.     case FUNCTKEY:
  823.       rsrc_gaddr(R_TREE, FUNCTEDT, &obj_tmp);
  824.       ted_fnum = (TEDINFO *) obj_tmp[FUNCNAME].ob_spec;
  825.       sprintf(ted_fnum->te_ptext, "%2d", funcindex+1);
  826.       ted_tmp = (TEDINFO *) obj_tmp[FUNCBODY].ob_spec;
  827.       strcpy((char *) ted_tmp->te_ptext, fstrings[funcindex]);
  828.       form_center(obj_tmp, &cx, &cy, &cw, &ch);
  829.       form_dial(FMD_START, 0, 0, 20, 10, cx, cy, cw, ch);
  830.       if (!fast) form_dial(FMD_GROW, 0, 0, 20, 10, cx, cy, cw, ch);
  831.       objc_draw(obj_tmp, 0, 5, cx, cy, cw, ch);
  832.       tmp = 0;
  833.       while (tmp != FUNCEXIT)
  834.       {
  835.         int i;
  836.         
  837.         tmp = form_do(obj_tmp, FUNCNAME);
  838.         switch (tmp)
  839.         {
  840.         case FUNCSHOW:
  841.           funcindex = atoi(ted_fnum->te_ptext) - 1;
  842.           if (funcindex < 0)
  843.             funcindex = NFSTRINGS - 3;
  844.           else if (funcindex > NFSTRINGS - 3)
  845.             funcindex = 0;
  846.           strcpy((char *) ted_tmp->te_ptext, fstrings[funcindex]);
  847.           objc_draw(obj_tmp, FUNCBODY, 5, cx, cy, cw, ch);
  848.           sprintf(ted_fnum->te_ptext, "%2d", funcindex+1);
  849.           objc_draw(obj_tmp, FUNCNAME, 5, cx, cy, cw, ch);
  850.           break;
  851.         case FUNCPREV:
  852.           funcindex --;
  853.           if (funcindex < 0)
  854.             funcindex = NFSTRINGS - 3;
  855.           sprintf(ted_fnum->te_ptext, "%2d", funcindex+1);
  856.           objc_draw(obj_tmp, FUNCNAME, 5, cx, cy, cw, ch);
  857.           strcpy((char *) ted_tmp->te_ptext, fstrings[funcindex]);
  858.           objc_draw(obj_tmp, FUNCBODY, 5, cx, cy, cw, ch);
  859.           break;
  860.         case FUNCNEXT:
  861.           funcindex ++;
  862.           if (funcindex > NFSTRINGS - 3)
  863.             funcindex = 0;
  864.           sprintf(ted_fnum->te_ptext, "%2d", funcindex+1);
  865.           objc_draw(obj_tmp, FUNCNAME, 5, cx, cy, cw, ch);
  866.           strcpy((char *) ted_tmp->te_ptext, fstrings[funcindex]);
  867.           objc_draw(obj_tmp, FUNCBODY, 5, cx, cy, cw, ch);
  868.           break;
  869.         case FUNCENT:
  870.           funcindex = atoi(ted_fnum->te_ptext) - 1;
  871.           strcpy(fstrings[funcindex], ted_tmp->te_ptext);
  872.           fstrings[funcindex][i] = ted_tmp->te_ptext[i];
  873.           strcpy((char *) ted_tmp->te_ptext, fstrings[funcindex]);
  874.           objc_draw(obj_tmp, FUNCBODY, 5, cx, cy, cw, ch);
  875.           break;
  876.         }
  877.         objc_change(obj_tmp, tmp, 0, cx, cy, cw, ch, NONE, 1);
  878.       }
  879.       if (!fast) form_dial(FMD_SHRINK, 0, 0, 20, 10, cx, cy, cw, ch);
  880.       form_dial(FMD_FINISH, 0, 0, 20, 10, cx, cy, cw, ch);
  881.       objc_change(obj_tmp, tmp, 0, cx, cy, cw, ch, NONE, 0);
  882.       break;
  883.  
  884.     case MFREE:
  885.       memory();
  886.       break;
  887.  
  888.     case MFAST:
  889.       menu_icheck(menubar, MFAST, fast);
  890.       fast = !fast;
  891.       break;
  892.  
  893.     case OVERSTRI:
  894.       overstrike = !overstrike;
  895.       menu_icheck(menubar, OVERSTRI, overstrike);
  896.       break;
  897.  
  898.     case FNTSYS:
  899.     case FNTOWN:
  900.     case FNTALT:
  901.     case FNTBIG:
  902.     case FNTTINY:
  903.     case FNTUNKNW:
  904.     /* Add new font menu items here! */
  905.       for (cnt = 0; fontmenuobj[cnt] != 0; cnt++)
  906.       {
  907.         if (fontmenuobj[cnt] != msgbuff[4])
  908.         {
  909.           if (cnt < fontsavail)
  910.             objc_change(menubar, fontmenuobj[cnt], 0, 0, 0, 0, 0,
  911.           NONE, 0);
  912.           else
  913.             objc_change(menubar, fontmenuobj[cnt], 0, 0, 0, 0, 0,
  914.           DISABLED, 0);
  915.         }
  916.         else
  917.           curfont = fnttbl[cnt];
  918.       }
  919.       objc_change(menubar, msgbuff[4], 0, 0, 0, 0, 0, CHECKED, 0);
  920.       break;
  921.  
  922.     case PRTBOTOM:
  923.       if (outwind)
  924.       {
  925.         w[outwind].ptr_status = LOG_BOTOM;
  926.         printer_mark(outwind);
  927.         w_rename(outwind, NULL);
  928.       }
  929.       break;
  930.  
  931.     case PRTTOP:
  932.       if (outwind)
  933.       {
  934.         w[outwind].ptr_status = LOG_TOP;
  935.         printer_mark(outwind);
  936.         w_rename(outwind, NULL);
  937.       }
  938.       break;
  939.  
  940.     case PRTWIND:
  941.       if (outwind)
  942.       {
  943.         printer_mark(outwind);
  944.         dump_window(outwind);
  945.       }
  946.       break;
  947.  
  948.     case PRTSTOP:
  949.       if (outwind)
  950.       {
  951.         w[outwind].ptr_status = LOG_NONE;
  952.         printer_mark(outwind);
  953.         w_rename(outwind, NULL);
  954.       }
  955.       break;
  956.  
  957.     case INPUTWIN:
  958.     case PASTE:
  959.       sel_inp_mode = msgbuff[4];
  960.       graf_mouse(USER_DEF, rmbmform);
  961.       break;
  962.  
  963.     case RESETAUX:
  964.       if (rs232_reset())
  965.         Cauxout(0x11);    /* send XOFF    */
  966.       break;
  967.  
  968.     case ASSRD:        /* Assert RTS/DTR. */
  969.         Offgibit(~0x18);
  970.         break;
  971.  
  972.     case RESRD:        /* Reset RTS/DTR. */
  973.         Ongibit(0x18);
  974.         break;
  975.  
  976.     case AUDIBELL:
  977.       audibell = !audibell;
  978.       objc_change(menubar, AUDIBELL, 0, 0, 0, 0, 0,
  979.         audibell? CHECKED: 0, 0);
  980.       break;
  981.  
  982.     case VISIBELL:
  983.       visibell = !visibell;
  984.       objc_change(menubar, VISIBELL, 0, 0, 0, 0, 0,
  985.         visibell? CHECKED: 0, 0);
  986.       break;
  987.  
  988.     case TOPONBEL:
  989.       toponbel = !toponbel;
  990.       objc_change(menubar, TOPONBEL, 0, 0, 0, 0, 0,
  991.         toponbel? CHECKED: 0, 0);
  992.       break;
  993.       
  994.     case SHRNKWIN:    /* Shrink window to iconic size */
  995.       if (outwind)
  996.       {
  997.         outwind = w_shrink(outwind);
  998.         outport = find_port(outwind);
  999.       }
  1000.       break;
  1001.  
  1002.     case BOTTOMTO:    /* send bottom window to top */
  1003.       w_bottom();
  1004.       break;
  1005.  
  1006.     case WINSTYLE:    /* enable/disable sliders and arrows for new windows */
  1007.       sliders = !sliders;
  1008.       menu_icheck(menubar, WINSTYLE, sliders);
  1009.       break;
  1010.  
  1011.     case HIDEWIN:    /* send top window to bottom */
  1012.       if (outwind = w_hide())
  1013.       {
  1014.         outport = find_port(outwind);
  1015.         printer_mark(outwind);
  1016.       }
  1017.       break;
  1018.  
  1019.     case MOVEWIN:
  1020.       if (outwind)
  1021.       {
  1022.         graf_mouse(POINT_HAND, &dummy);
  1023.         evnt_button(1, 1, 1, &mx, &my, &dummy, &dummy);
  1024.         wind_get(outwind, WF_CURRXYWH, &dummy, &dummy, &ww, &wh);
  1025.         if (graf_dragbox(ww, wh, mx, my,
  1026.           scr_x, scr_y, scr_w + ww, scr_h + wh, &mx, &my))
  1027.             w_move(outwind, mx, my, ww, wh);
  1028.         graf_mouse(sel_inp_mode? USER_DEF: ARROW, rmbmform);
  1029.       }
  1030.       break;
  1031.  
  1032.     case OSIZEWIN:
  1033.       if (outwind)
  1034.       {
  1035.         outwind = w_full(outwind);
  1036.         outport = find_port(outwind);
  1037.       }
  1038.       break;
  1039.  
  1040.     case CLOSEWIN:
  1041.       if (outwind = proto_close(outwind))
  1042.       {
  1043.         printer_mark(outwind);
  1044.         outport = find_port(outwind);
  1045.       }
  1046.       if (!uw_runs && !find_wind(1))
  1047.       {
  1048.         menu_tnormal(menubar, msgbuff[3], 1);
  1049.         goto init;
  1050.       }
  1051.       break;
  1052.  
  1053.     case WINTITLE:    /* enable/disable window headers */
  1054.       titles = !titles;
  1055.       menu_icheck(menubar, WINTITLE, titles);
  1056.       break;
  1057.  
  1058.     case SETCONF:    /* set rs232 port configuration */
  1059.       getrsconf();
  1060.       if (s_dial(RSCONF, 3) == RCOK)
  1061.         setrsconf();
  1062.       break;
  1063.  
  1064.     case WINCLEAR:    /* clear current window */
  1065.       if (outwind)
  1066.       {
  1067.         w[outwind].ptr_status = LOG_NONE;
  1068.         w_output(outwind, "\032");
  1069.       }
  1070.       break;
  1071.     }
  1072.     menu_tnormal(menubar, msgbuff[3], 1);
  1073.     break;
  1074.  
  1075.       case WM_NEWTOP:
  1076.       case WM_TOPPED:
  1077.     if (!locked)
  1078.       w_top(msgbuff[3]);
  1079.     break;
  1080.  
  1081.       case WM_SIZED:
  1082.       case WM_MOVED:
  1083.     if (!locked)
  1084.       w_move(msgbuff[3], msgbuff[4], msgbuff[5], msgbuff[6], msgbuff[7]);
  1085.     break;
  1086.  
  1087.       case WM_CLOSED:
  1088.         if (locked) break;
  1089.     if (cnt = proto_close(msgbuff[3]))
  1090.     {
  1091.       if (msgbuff[3] == outwind)    /* was keyboard input window closed? */
  1092.         outwind = cnt;
  1093.       printer_mark(outwind);
  1094.       outport = find_port(outwind);
  1095.     }
  1096.     if (!uw_runs && !find_wind(1))
  1097.     {
  1098.       goto init;
  1099.     }
  1100.     break;
  1101.  
  1102.       case WM_REDRAW:
  1103.         if (highlighted_wdes == msgbuff[3])
  1104.     {    /* this window has highlighted text, redraw all of window*/
  1105.       register struct wi_str *wp = &w[msgbuff[3]];
  1106.       w_redraw(msgbuff[3], FM_COPY, wp->x, wp->y, wp->w, wp->h);
  1107.     }
  1108.     else
  1109.       /* redraw only damaged part */
  1110.       w_redraw(msgbuff[3], FM_COPY, msgbuff[4], msgbuff[5], msgbuff[6], msgbuff[7]);
  1111.     break;
  1112.  
  1113.       case WM_FULLED:
  1114.     if (locked) break;
  1115.     outwind = w_full(msgbuff[3]);
  1116.     outport = find_port(outwind);
  1117.     break;
  1118.  
  1119.       case WM_ARROWED:
  1120.     if (!locked)
  1121.       w_arrow(msgbuff[3], msgbuff[4]);
  1122.     break;
  1123.  
  1124.       case WM_HSLID:
  1125.       case WM_VSLID:
  1126.     if (!locked)
  1127.       w_slide(msgbuff[3], msgbuff[0] == WM_HSLID, msgbuff[4]);
  1128.     break;
  1129.       }
  1130.     }
  1131.     if ((event & MU_BUTTON) && ! locked)
  1132.     {
  1133.       if (sel_inp_mode && buttonstate) /* select input mode and button down */
  1134.       {
  1135.         int found;
  1136.  
  1137.     graf_mouse(ARROW, &dummy);
  1138.     if ((found = wind_find(mx, my)) != 0) {
  1139.       outwind = found;
  1140.       outport = find_port(outwind);
  1141.       if (sel_inp_mode == PASTE)
  1142.           proto_out(outport, pastebuff, strlen(pastebuff));
  1143.     }
  1144.     evnt_button(1, 2, 0, &dummy, &dummy, &dummy, &dummy);
  1145.     buttonstate = 0;
  1146.     sel_inp_mode = FALSE;
  1147.       }
  1148.       else if (my < scr_y)    /* is mouse on menu bar? */
  1149.       {    /* yes, disable menu bar if button down */
  1150.         if (buttonstate)
  1151.     {
  1152.           objc_change(menubar, DESK, 0, 0, 0, 0, 0,
  1153.             menonoff? DISABLED: NORMAL, menonoff);
  1154.           menu_bar(menubar, menonoff = !menonoff);
  1155.       if (menonoff)
  1156.         graf_mouse(ARROW, &dummy);
  1157.       else
  1158.         graf_mouse(USER_DEF, rmbmform);
  1159.       evnt_button(1, 2, 0, &dummy, &dummy, &dummy, &dummy);
  1160.       buttonstate = 0;
  1161.     }
  1162.       }
  1163.       else    /* button click in work area */
  1164.       {    /* handle text selection or output or mouse packet */
  1165.         int found, found1, x1, y1, x2, y2, w_x, w_y, w_w, w_h;
  1166.  
  1167.     if ((found = wind_find(mx, my)) != 0)
  1168.     {
  1169.       wind_get(found, WF_WORKXYWH, &w_x, &w_y, &w_w, &w_h);
  1170.       if (mx >= w_x && mx < w_x + w_w && my >= w_y && my <w_y + w_h)
  1171.       { /* in window, fill paste buffer */
  1172.         if (clicks > 1 && buttonstate)
  1173.         {
  1174.           y1 = (my - w_y - Y0) / w[found].font->inc_y;
  1175.           copy_text(found, 0, y1, w[found].x_chrs - 1, y1, pastebuff);
  1176.           evnt_button(3, 2, 0, &dummy, &dummy, &dummy, &dummy);
  1177.           regionflag = 0;
  1178.         }
  1179.         else if (buttonstate)    /* if button down */
  1180.         {
  1181.           x1 = (mx - w_x - X0) / w[found].font->inc_x;
  1182.           y1 = (my - w_y - Y0) / w[found].font->inc_y;
  1183.           regionflag = 1;
  1184.           found1 = found;
  1185.         }
  1186.         else if (regionflag && found == found1)
  1187.         {    /* button up */
  1188.           x2 = (mx - w_x - X0) / w[found].font->inc_x;
  1189.           y2 = (my - w_y - Y0) / w[found].font->inc_y;
  1190.           if (y2 == y1 && x2 == x1)
  1191.           {     /* simple click on char; select word */
  1192.             copy_word(found, x1, y1, pastebuff);
  1193.           }
  1194.           else if (y2 > y1 || (y2 == y1 && x2 > x1))
  1195.             copy_text(found, x1, y1, x2-1, y2, pastebuff);
  1196.           else
  1197.         copy_text(found, x2+1, y2, x1, y1, pastebuff);
  1198.         }
  1199.       }
  1200.       else
  1201.       { /* in border */
  1202.         /* send paste buffer and select keyboard window*/
  1203.         if (buttonstate)    /* if button down */
  1204.         {
  1205.           char * pptr = pastebuff;
  1206.           outwind = found;
  1207.           outport = find_port(outwind);
  1208.           if (clicks > 1)
  1209.               proto_out(outport, pptr, strlen(pptr));
  1210.         }
  1211.         regionflag = 0;
  1212.       }
  1213.     }
  1214.     else
  1215.     {    /* not in window or border */
  1216.         /* clear paste buffer and erase any current marks */
  1217.       pastebuff[0] = '\0';
  1218.       regionflag = 0;
  1219.       copy_text(1, 1, 1, 0, 0, pastebuff);
  1220.     }
  1221.       }
  1222.       buttonstate = buttonstate? 0: 2;    /* toggle buttonstate */
  1223.     }
  1224.     if (event & MU_M1)    /* mouse moved into or out of work area */
  1225.     {
  1226.       if (!sel_inp_mode && !menonoff && !locked)
  1227.     graf_mouse(m1inout? USER_DEF: ARROW, rmbmform);
  1228.       m1inout = ! m1inout;
  1229.     }
  1230.   }
  1231. }
  1232. /*
  1233.  * printer_mark(wnd) places check marks in the apropriate places in the
  1234.  * printer menu.
  1235.  */
  1236. printer_mark (wnd)
  1237. {
  1238.     objc_change(menubar, PRTBOTOM, 0, 0, 0, 0, 0,
  1239.       (w[wnd].ptr_status & LOG_BOTOM)? CHECKED: NONE, 0);
  1240.  
  1241.     objc_change(menubar, PRTTOP, 0, 0, 0, 0, 0,
  1242.       (w[wnd].ptr_status & LOG_TOP)? CHECKED: NONE, 0);
  1243. }
  1244.  
  1245. /*
  1246.  * s_dial performs a simple dialog with buttons and text only.
  1247.  * The index of the terminating button is returned.
  1248.  * If action == 1, the dialog is displayed.  If action == 2, it is
  1249.  * removed.  If action == 3, both operations are done and form_do is
  1250.  * called.
  1251.  */
  1252. int s_dial(tree, action)
  1253. int tree, action;
  1254. {
  1255.   int tmp = 0;
  1256.   int cx, cy, cw, ch;
  1257.   OBJECT *obj_tmp;
  1258.  
  1259.   rsrc_gaddr(R_TREE, tree, &obj_tmp);
  1260.   form_center(obj_tmp, &cx, &cy, &cw, &ch);
  1261.   if (action & 1) {
  1262.     form_dial(FMD_START, 0, 0, 20, 10, cx, cy, cw, ch);
  1263.     if (!fast) form_dial(FMD_GROW, 0, 0, 20, 10, cx, cy, cw, ch);
  1264.     objc_draw(obj_tmp, 0, 5, cx, cy, cw, ch);
  1265.   }
  1266.   if (action == 3) {
  1267.     tmp = form_do(obj_tmp, 0);
  1268.   }
  1269.   if (action & 2) {
  1270.     if (!fast) form_dial(FMD_SHRINK, 0, 0, 20, 10, cx, cy, cw, ch);
  1271.     form_dial(FMD_FINISH, 0, 0, 20, 10, cx, cy, cw, ch);
  1272.     objc_change(obj_tmp, tmp, 0, cx, cy, cw, ch, NONE, 0);
  1273.   }
  1274.     return (tmp);
  1275. }
  1276.  
  1277. /*
  1278.  * set_menu_string sets the menu string for the specified menu object to
  1279.  * newstr.
  1280.  */
  1281. set_menu_string(newstr, object)
  1282. register char * newstr;
  1283. int object;
  1284. {
  1285.   register char * oldstr;
  1286.  
  1287.   oldstr = (char *) menubar[object].ob_spec + 2;
  1288.   while (*oldstr && *newstr)
  1289.     *oldstr++ = *newstr++;
  1290.   if (*oldstr)
  1291.       *oldstr = ' ';
  1292. }
  1293.  
  1294. size_dial()
  1295. {
  1296.   /*
  1297.    * Enter rows and columns dialog
  1298.    */
  1299.   int cx, cy, cw, ch;
  1300.   char *rowstr, *colstr;
  1301.   rsrc_gaddr(R_TREE, WINDSIZE, &obj_tmp);
  1302.   ted_tmp = (TEDINFO *) obj_tmp[WINDROWS].ob_spec;
  1303.   rowstr = ((char *)ted_tmp->te_ptext);
  1304.   if (atoi(rowstr) < 2)
  1305.     strcpy (rowstr, "24");
  1306.   ted_tmp = (TEDINFO *) obj_tmp[WINDCOLS].ob_spec;
  1307.   colstr = ((char *)ted_tmp->te_ptext);
  1308.   if (atoi(colstr) < 2)
  1309.     strcpy (colstr, "80");
  1310.   form_center(obj_tmp, &cx, &cy, &cw, &ch);
  1311.   form_dial(FMD_START, 0, 0, 20, 10, cx, cy, cw, ch);
  1312.   if (!fast)
  1313.     form_dial(FMD_GROW, 0, 0, 20, 10, cx, cy, cw, ch);
  1314.   objc_draw(obj_tmp, 0, 5, cx, cy, cw, ch);
  1315.   tmp = form_do(obj_tmp, WINDROWS);
  1316.   if (!fast)
  1317.     form_dial(FMD_SHRINK, 0, 0, 20, 10, cx, cy, cw, ch);
  1318.   form_dial(FMD_FINISH, 0, 0, 20, 10, cx, cy, cw, ch);
  1319.   objc_change(obj_tmp, tmp, 0, cx, cy, cw, ch, NONE, 0);
  1320.   if (tmp == WINDCANC)
  1321.     return(FALSE);
  1322.   xsiz = atoi(colstr);
  1323.   ysiz = atoi(rowstr);
  1324.   if (xsiz < 2)
  1325.     xsiz = 2;
  1326.   if (xsiz > 300)
  1327.     xsiz = 300;
  1328.   if (ysiz < 2)
  1329.     ysiz = 2;
  1330.   if (ysiz > 300)
  1331.     ysiz = 300;
  1332.   return (TRUE);
  1333. }
  1334.